package com.liqw.core;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * WebDriver通用工具类（封装元素操作、窗口切换、等待等通用逻辑）
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE) // 禁止实例化
public class WebDriverUtils {

    /**
     * 等待元素可见（显式等待）
     * @param driver WebDriver实例
     * @param by 元素选择器
     * @return 可见的元素（若超时返回null）
     */
    public static WebElement waitForElementVisible(WebDriver driver, By by) {
        try {
            return new WebDriverWait(driver, Duration.ofSeconds(Config.WAIT_TIMEOUT_SECONDS))
                    .until(ExpectedConditions.visibilityOfElementLocated(by));
        } catch (TimeoutException e) {
            // 元素未出现时返回null，由调用方决定是否处理
            return null;
        }
    }

    /**
     * 点击元素（点击前检查可见性）
     * @param driver WebDriver实例
     * @param element 待点击元素
     * @return 是否点击成功
     */
    public static boolean clickElement(WebDriver driver, WebElement element) {
        if (element == null || !element.isDisplayed() || !element.isEnabled()) {
            return false;
        }
        try {
            // 处理元素被遮挡的情况（滚动到元素位置）
            ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
            element.click();
            // 点击后短暂等待（避免页面未响应）
            TimeUnit.MILLISECONDS.sleep(Config.PAGE_LOAD_WAIT_MS);
            return true;
        } catch (ElementClickInterceptedException e) {
            // 若点击被拦截，尝试JS点击
            ((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 切换到新打开的窗口（并关闭原窗口）
     * @param driver WebDriver实例
     * @return 新窗口的句柄（若未找到返回null）
     */
    public static String switchToNewWindow(Set<String> originalHandles, WebDriver driver) {
        log.info("originalHandles size={}", originalHandles.size());
        while (true) {
            Set<String> currentHandles = driver.getWindowHandles();
            log.info("等待新窗口打开... currentHandles size={}", currentHandles.size());
            currentHandles.removeAll(originalHandles);
            if (currentHandles.size() == 1) {
                String newHandle = currentHandles.iterator().next();
                driver.switchTo().window(newHandle);
                return newHandle;
            }
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return null;
            }
        }
    }

    /**
     * 从URL提取域名（用于登录状态判断）
     */
    public static String extractDomain(String url) {
        if (url == null || url.trim().isEmpty()) {
            return "";
        }
        // 移除协议（http/https）
        String domain = url.replaceFirst("https?://", "");
        // 移除路径和端口
        Matcher matcher = Pattern.compile("^[^:/]+").matcher(domain);
        return matcher.find() ? matcher.group() : domain;
    }

    /**
     * 安全关闭窗口并切换回原窗口
     * @param driver WebDriver实例
     * @param currentHandle 当前窗口句柄（需关闭的窗口）
     * @param targetHandle 目标窗口句柄（切换回的窗口）
     */
    public static void closeWindowAndSwitchBack(WebDriver driver, String currentHandle, String targetHandle) {
        if (currentHandle == null || targetHandle == null || driver == null) {
            return;
        }
        try {
            driver.switchTo().window(currentHandle).close();
            driver.switchTo().window(targetHandle);
        } catch (NoSuchWindowException e) {
            // 窗口已关闭时忽略
        }
    }
}